package com.cos.test;

import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import sun.net.www.content.image.png;

import java.io.*;
import java.util.List;

/**
 * @author: COS
 * @time: 2023/1/10 15:25
 * @description:
 */
public class Demo3 {
    public static void main(String[] args) throws IOException {
        jiHuoHuoGuaQi();
    }


    public static void jiHuoHuoGuaQi(){
        //1 获取activiti 引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        //2 获取运行时 服务
        RuntimeService runtimeService = engine.getRuntimeService();
        //3 流程实例查询
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                // 设置实例id来查询
                .processInstanceId("10001")
                .singleResult();
        //4 判断实例状态
        if (processInstance.isSuspended()) {
            //true 已被挂起 激活
            runtimeService.activateProcessInstanceById(processInstance.getId());
            System.out.println(processInstance.getName()+"流程已被重新激活");
        }else{
            //false 注册 设置挂起状态
            // 设置挂起
            runtimeService.suspendProcessInstanceById(processInstance.getId());
            System.out.println(processInstance.getName()+"流程已被挂起");
        }
    }


    //删除流程
    public static void deleteProcess(){
        //1 获取activiti引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        //2 获取仓储服务
        RepositoryService repositoryService = engine.getRepositoryService();
        //3 删除
        repositoryService.deleteDeployment("2501",true);
    }


    /**
     * @author: COS
     * @return:
     * @time: 2023/1/10 16:25
     * @description:
     * 之前工作流程并没有和我们实际数据库上的业务表进行关联,如请假相关的工作流程
     * 没法知道是那个人请假,请假多久,理由是什么,因为在整个业务流程当中都没有任务数据
     * 可以和我们实际的业务表(请假表) 关联,就无法获取业务表的数据,进行业务操作(设置是否同意,设置拒绝理由)
     * 所以在我们启动/创建一个流程实例的时候,可以设置一个业务键businessKey
     * 这个businessKey 可以作为我们业务表的外键表使用,设置业务表的主键进去
     * 这样在我们工作流程当中,就可以使用这个businessKey来关联业务层,获取业务数据
     * 进行业务逻辑操作
     */
    public static void createProcessInstance() {
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = engine.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId("7501")
                .singleResult();
        RuntimeService runtimeService = engine.getRuntimeService();
        // 设置业务表的主键 例如 请假表的主键,这样在业务过程我们可以通过这个业务键 获取对应的
        // 业务表的数据,进行业务逻辑判断或者操作
        ProcessInstance processInstance = runtimeService.
                startProcessInstanceById(processDefinition.getId(),
                        "1999");//请假表ID
        System.out.println(processInstance.getId());
        System.out.println(processInstance.getName());
        System.out.println(processInstance.getProcessDefinitionId());
    }

    /**
     * @author: COS
     * @return:
     * @time: 2023/1/10 16:07
     * @description: 获取流程历史信息
     */
    public static void getHistory() {
        //1 获取activi引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        //2 获取历史服务
        HistoryService historyService = engine.getHistoryService();
        //3 获取历史列表
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .processDefinitionId("myProcess_1:1:5004")
                // 设置获取的历史信息使用开始时间进行排序
                .orderByHistoricActivityInstanceStartTime()
                // 正序  desc降序
                .asc()
                //获取列表数据
                .list();
        //4 遍历输出信息
        for (HistoricActivityInstance historicActivityInstance : list) {
            //任务id
            System.out.println(historicActivityInstance.getActivityId());
            //任务名
            System.out.println(historicActivityInstance.getActivityName());
            //任务类型
            System.out.println(historicActivityInstance.getActivityType());
        }
    }

    public static void xx() throws IOException {
        FileInputStream f = new FileInputStream("bpmnOS.png");
        byte[] data = new byte[f.available()];
        FileOutputStream os = new FileOutputStream("C:\\Users\\cos\\Desktop\\a.png");
        f.read(data);
        os.write(data);
    }

    /**
     * @author: COS
     * @return:
     * @time: 2023/1/10 15:25
     * @description: 下载流程图 和 流程图片
     */
    public static void downloadBpmn() throws IOException {
        //1 获取activiti引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        //2 获取仓储服务
        RepositoryService repositoryService = engine.getRepositoryService();
        //3 通过仓储服务获取流程定义对象
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                // 通过部署id获取流程定义对象
//                .deploymentId("5001")
//                .processDefinitionKey("myProcess_1")
                .processDefinitionId("myProcess_1:1:5004")
                .singleResult();
        System.out.println("=======================>" + processDefinition);
        //4 使用存储服务,通过流程定义id来获取资源
        System.out.println(processDefinition.getResourceName());
        System.out.println(processDefinition.getDiagramResourceName());
        InputStream bpmnIS = repositoryService.
                getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
        InputStream pngIS = repositoryService.
                getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName());
        //5 通过
        // 设置自定义字节缓冲区
        FileOutputStream bpmnOS = new FileOutputStream("bpmnOS.bpmn");
        byte[] data = new byte[1024];
        int i;
        while ((i = bpmnIS.read(data)) != -1) {
            bpmnOS.write(data, 0, i);
        }
        FileOutputStream pngOS = new FileOutputStream("bpmnOS.png");
        byte[] data2 = new byte[1024];
        int i2;
        while ((i2 = pngIS.read(data2)) != -1) {
            pngOS.write(data2, 0, i2);
        }

        bpmnOS.close();
        pngIS.close();
    }

}
